<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <th:block th:include="include :: header('琦风公寓-每月账单列表')"/>
    <style>
        /* 手写字体样式定义，确保所有需要手写效果的元素生效 */
        .handwriting {
            font-family: '楷体';
        }
    </style>
    <th:block th:include="include :: select2-css"/>
    <th:block th:include="include :: bootstrap-select-css"/>
</head>
<body class="gray-bg">
<div class="container-div">
    <div class="row">
        <div class="col-sm-12 search-collapse">
            <form id="formId">
                <div class="select-list">
                    <ul>
                        <li >
                            单元号：<select name="unit" th:with="type=${@dict.getType('qif_room_unit')}">
                            <option value="">所有</option>
                            <option th:each="dict : ${type}" th:text="${dict.dictLabel}"
                                    th:value="${dict.dictValue}"></option>
                        </select>
                        </li>
                        <li>
                            房间:<select id="roomId" name="roomId" class="form-control " >
                            <option value="">所有</option>
                            <option th:each="room : ${roomList}" th:text="${room['roomNum']}" th:value="${room['roomId']}"></option>
                        </select>
                        </li>
                        <!-- 搜索条件中的交租日多选下拉框 -->
                        <li>
                            交租日:
                            <select id="rentPayDates" name="rentPayDates" class="noselect2 selectpicker "
                                    data-none-selected-text="请选择交租日"  multiple style="width: 110px">
                                <option th:each="date:${rentPayDateList}" th:value="${date}"
                                        th:text="${date} + '日'"></option>
                            </select>
                        </li>
                        <li>
                            是否结算：<select name="status" th:with="type=${@dict.getType('qif_bill_is_settlement')}" >
                            <option value="">所有</option>
                            <option th:each="dict : ${type}" th:text="${dict.dictLabel}"
                                    th:value="${dict.dictValue}"></option>
                        </select>
                        <li>
                            月份：
                            <select name="queryYear" id="queryYear" class="form-control selectpicker " data-live-search="false" >
                                <!-- 动态生成年份 -->
                            </select>
                            <span class="select-span">年</span>
                            <select name="queryMonth" id="queryMonth" class="form-control selectpicker " data-live-search="false" >
                                <!-- 动态生成月份 -->
                            </select>
                            <span class="select-span">月</span>
                        </li>
                        <li>
                            <a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i
                                    class="fa fa-search"></i>&nbsp;搜索</a>
                            <a class="btn btn-warning btn-rounded btn-sm" onclick="resetForm()"><i
                                    class="fa fa-refresh"></i>&nbsp;重置</a>
                        </li>
                    </ul>
                </div>
            </form>
        </div>
        <div class="btn-group-sm" id="toolbar" role="group">
            <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="qif:bill:export">
                <i class="fa fa-upload"></i> 导出本月账单
            </a>
            <!-- 新增：生成本月账单按钮 -->
            <a class="btn btn-success" onclick="generateCurrentMonthBills()" shiro:hasPermission="qif:bill:generate">
                <i class="fa fa-plus-circle"></i> 生成本月账单
            </a>
        </div>
        <div class="col-sm-12 select-table table-striped">
            <table id="bootstrap-table"></table>
        </div>
    </div>
</div>

<!-- 1. 账单预览与生成弹框 -->
<div class="modal fade" id="billImageModal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title">账单预览与生成</h4>
            </div>
            <div class="modal-body">
                <!-- 账单预览区域（核心：只保留用户名称、单元、房间号） -->
                <div id="billPreview"
                     style="width: 700px; margin: 0 auto; padding: 20px; border: 1px solid #333; background: #fff; line-height: 1.5; position: relative;">
                    <!-- 标题与单号（修改后：flex布局实现水平对齐） -->
                    <div style="display: flex; justify-content: center; align-items: center; position: relative; margin-bottom: 15px;">
                        <h2 style="margin: 0; font-weight: bold; font-family: '楷体', 'KaiTi', serif;">
                            房租、水、电费（专用）收据</h2>
                        <!-- 编号通过绝对定位右对齐，与标题在同一行 -->
                        <span style="position: absolute; right: 0; font-size: 18px; font-weight: bold; color: #d9534f;"
                              id="previewBillNumber">0000001</span>
                    </div>

                    <!-- 用户核心信息（只保留：用户名称、单元、房间号） -->
                    <div style="margin-bottom: 15px; display: flex; justify-content: space-between; font-size: 16px; font-family: '楷体', 'KaiTi', serif;">
                        <div>
                            <span style="font-weight: bold;">单元：</span>
                            <span id="previewUnit" class="handwriting">-</span>
                        </div>
                        <div>
                            <span style="font-weight: bold;">房间号：</span>
                            <span id="previewRoomNum" class="handwriting">-</span>
                        </div>
                        <div>
                            <span style="font-weight: bold;">日期：</span>
                            <span id="previewDate" class="handwriting">-</span>
                        </div>
                    </div>

                    <!-- 费用表格 -->
                    <table style="width: 100%; border-collapse: collapse; margin-bottom: 15px; border: 1px solid #333; font-family: '楷体', 'KaiTi', serif;">
                        <thead>
                        <tr style="background: #f5f5f5;">
                            <th style="border: 1px solid #333; padding: 6px; text-align: center;">项目</th>
                            <th style="border: 1px solid #333; padding: 6px; text-align: center;">本月</th>
                            <th style="border: 1px solid #333; padding: 6px; text-align: center;">上月</th>
                            <th style="border: 1px solid #333; padding: 6px; text-align: center;">实用</th>
                            <th style="border: 1px solid #333; padding: 6px; text-align: center;">单价</th>
                            <th style="border: 1px solid #333; padding: 6px; text-align: center;">金额（元）</th>
                        </tr>
                        </thead>
                        <tbody>
                        <!-- 水费行 -->
                        <tr>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;">水费(吨)</td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;" class="handwriting"
                                id="previewWaterThisMonth">-
                            </td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;" class="handwriting"
                                id="previewWaterLastMonth">-
                            </td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;" class="handwriting"
                                id="previewWaterUsage">-
                            </td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"
                                id="previewWaterUnitPrice">5.00
                            </td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;" class="handwriting"
                                id="previewWaterAmount">-
                            </td>
                        </tr>
                        <!-- 电费行 -->
                        <tr>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;">电费(度)</td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;" class="handwriting"
                                id="previewElectricityThisMonth">-
                            </td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;" class="handwriting"
                                id="previewElectricityLastMonth">-
                            </td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;" class="handwriting"
                                id="previewElectricityUsage">-
                            </td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"
                                id="previewElectricityUnitPrice">0.84
                            </td>
                            <!-- 电费金额行（修改后：内容超出单元格显示） -->
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;position: relative;overflow: visible;">
                                <!-- 金额内容：脱离文档流，定位到单元格外部 -->
                                <span id="previewElectricityAmount" style="position: absolute;bottom: -10px; left: 50%; transform: translateX(-50%); background: #fff; padding: 0 5px;">-</span>
                            </td>
                        </tr>
                        <!-- 公共事业服务费行 -->
                        <tr>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;">公共事业服务费</td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"
                                id="previewPublicServiceUnitPrice">0.46
                            </td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                        </tr>
                        <!-- 房租行 -->
                        <tr>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;">房租</td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;" class="handwriting"
                                id="previewRentAmount">-
                            </td>
                        </tr>
                        <!-- 卫生费行 -->
                        <tr>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;">卫生费/管理费</td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;"></td>
                            <td style="border: 1px solid #333; padding: 6px; text-align: center;" class="handwriting"
                                id="previewSanitationFee">-
                            </td>
                        </tr>

                        <!-- 合计金额 -->
                        <tr>
                            <!-- 1. colspan="6" 合并所有列，确保没有其他列显示 -->
                            <td style="border: 1px solid #333; padding: 10px; text-align: left; font-weight: bold; width: 100%;"
                                colspan="6">
                                <!-- 2. 父容器相对定位，用于子元素绝对定位 -->
                                <div style="position: relative; width: 100%;">
                                    <!-- 3. “合计人民币（大写）：” 靠左显示（默认左对齐） -->
                                    <span style="font-weight: bold;">合计人民币（大写）：</span>

                                    <!-- 4. 金额区域绝对定位靠右，与左侧文字分离 -->
                                    <div style="position: absolute; right: 10px; top: 0;">
                                        <span id="previewTotalAmountCapital"
                                              style="margin: 0 5px; font-size: 16px; font-weight: bold;"
                                              class="handwriting">零元整</span>
                                        <span style="font-weight: bold;">（￥：</span>
                                        <span id="previewTotalAmount"
                                              style="margin: 0 5px; font-size: 18px; font-weight: bold;"
                                              class="handwriting">-</span>
                                        <span style="font-weight: bold;">）</span>
                                    </div>
                                </div>
                            </td>
                        </tr>
                        </tbody>
                    </table>

                    <!-- 开票人与收款人 -->
                    <div style="display: flex; justify-content: space-between; font-size: 16px; font-family: '楷体', 'KaiTi', serif;">
                        <div>
                            <span style="font-weight: bold;">开票人：</span>
                            <span id="previewIssuer" class="handwriting">锜风公寓</span>
                        </div>
                        <div>
                            <span style="font-weight: bold;">收款人：</span>
                            <span id="previewCollector" class="handwriting">管理员</span>
                        </div>
                    </div>
                    <!-- 收款专用章容器 -->
                    <!--                    <div id="stampContainer" style="position: absolute; bottom: 345px; right: 185px; width: 130px; height: 57px;">-->
                    <!--                        <img id="stampImg" src="/img/shoukuanzhang.png" alt="收款专用章" style="width: 100%; height: auto; opacity: 0.8;">-->
                    <!--                    </div>-->
                </div>

            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                <!-- 直接显示确认保存按钮，删除生成图片按钮 -->
                <button type="button" class="btn btn-success" id="saveBtn">确认保存</button>
            </div>
        </div>
    </div>
</div>

<!-- 2. 图片放大查看弹框 -->
<div class="modal fade" id="imageZoomModal" tabindex="-1" role="dialog" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title">账单图片放大查看</h4>
            </div>
            <div class="modal-body" style="text-align: center;">
                <img id="zoomImage" src="" style="max-width: 100%; max-height: 80vh;"/>
            </div>
        </div>
    </div>
</div>
<!-- 引入html2canvas（确保先加载再使用） -->
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
<th:block th:include="include :: footer"/>
<!-- 引入若依内置Select2 CSS和JS -->
<th:block th:include="include :: select2-js"/>
<th:block th:include="include :: bootstrap-select-js"/>
<script th:inline="javascript">
    // 全局变量初始化（与后端权限、字典匹配）
    var editFlag = [[${@permission.hasPermi('qif:bill:edit')}]];
    var removeFlag = [[${@permission.hasPermi('qif:bill:remove')}]];
    var roomStatus = [[${@dict.getType('qif_room_status')}]];
    var unitTypes = [[${@dict.getType('qif_room_unit')}]];
    var billIsSettlement = [[${@dict.getType('qif_bill_is_settlement')}]];
    var prefix = ctx + "qif/bill";

    function resetForm() {
        // 1. 若依表单重置（清空输入框、单选框等）
        $.form.reset();
        // 2. 重置bootstrap-select组件（多选/下拉）
        $('#rentPayDates').val(null).selectpicker('refresh');
        $('select[name="unit"]').val('').selectpicker('refresh');
        $('#roomId').val('').selectpicker('refresh');
        $('select[name="status"]').val('').selectpicker('refresh');
        // 3. 重置年月选择器为当前年月
        const now = new Date();
        $('#queryYear').val(now.getFullYear()).selectpicker('refresh');
        $('#queryMonth').val(now.getMonth() + 1).selectpicker('refresh');
        $.table.search();
    }

    $(function () {
        // 初始化年份选择器（近5年，默认当前年）
        const now = new Date();
        const currentYear = now.getFullYear();
        const $year = $('#queryYear');
        for (let i = currentYear; i >= currentYear - 4; i--) {
            $year.append(`<option value="${i}">${i}</option>`);
        }
        $year.val(currentYear).selectpicker('refresh'); // 若依推荐用selectpicker刷新

        // 初始化月份选择器（1-12月，默认当前月）
        const $month = $('#queryMonth');
        for (let i = 1; i <= 12; i++) {
            const monthText = i.toString().padStart(2, '0'); // 补0显示（如01-12）
            $month.append(`<option value="${i}">${monthText}</option>`);
        }
        $month.val(now.getMonth() + 1).selectpicker('refresh');

        // 1. 公用：保存单元格数据（对接后端updateCell接口）
        function saveCellValue(billId, field, newValue) {
            if (!billId || newValue === '' || (field !== 'isSettlement' && (isNaN(newValue) || parseFloat(newValue) < 0))) {
                var tip = field === 'isSettlement' ? "请选择结算状态" : "请输入有效的非负数值！";
                $.modal.alertWarning(tip);
                return Promise.reject("无效参数");
            }
            return $.ajax({
                url: prefix + "/updateCell",
                type: "post",
                dataType: "json",
                contentType: "application/json",
                data: JSON.stringify({
                    billId: billId,
                    fieldName: field,
                    fieldValue: field === 'isSettlement' ? newValue : (field === 'actualPay' ? parseFloat(newValue) : parseInt(newValue))
                })
            });
        }

        // 2. 公用：单元格点击编辑逻辑（支持输入框/下拉框）
        function cellEditHandler(e, row, index, fieldType = 'input') {
            e.stopPropagation();
            // 定位编辑元素
            var $text = $(e.target).closest('.cell-text');
            if (!$text || $text.length === 0) {
                $.modal.alertWarning("元素异常，无法编辑");
                return null;
            }

            // 获取基础参数
            var field = $text.attr("data-field") || "";
            var billId = $text.attr("data-id") || "";
            var currentValue = $text.text().trim() || "";
            billId = billId.trim();

            // 校验账单ID
            if (!billId) {
                $.modal.alertWarning("账单ID无效，无法编辑");
                return null;
            }

            // 根据字段类型渲染编辑控件（输入框/下拉框）
            var $editCtrl;
            if (fieldType === 'select') {
                // 渲染“是否结算”下拉框（选项：0=是，1=否）
                $editCtrl = $('<select class="cell-input form-control" style="width: 100px; margin: 0 auto;">')
                    .append('<option value="0">是</option>')
                    .append('<option value="1">否</option>')
                    .val(currentValue === '是' ? '0' : (currentValue === '否' ? '1' : ''));
            } else {
                // 渲染输入框（支持数字/小数，实收款保留2位小数）
                var inputType = field === 'actualPay' ? 'number' : 'number';
                var step = field === 'actualPay' ? '0.01' : '1';
                $editCtrl = $('<input type="' + inputType + '" step="' + step + '" min="0" class="cell-input form-control" style="width: 80px; text-align: center; margin: 0 auto;">')
                    .val(currentValue.replace('¥', '') || ""); // 移除人民币符号
            }

            // 插入编辑控件，隐藏原文本
            $editCtrl.appendTo($text.parent());
            $text.hide();
            $editCtrl.focus();

            return {$text, $editCtrl, billId, field};
        }

        // 3. 公用：编辑控件失焦保存逻辑
        function cellSaveHandler(editData) {
            var {$text, $editCtrl, billId, field} = editData;
            var newValue = $editCtrl.val().trim();

            saveCellValue(billId, field, newValue)
                .done(function (res) {
                    if (res.code === 0) {
                        // 格式化显示值（金额加¥，结算状态转文字）
                        var showValue = field === 'actualPay' ? '¥' + (parseFloat(newValue) || 0) :
                            field === 'isSettlement' ? (newValue === '1' ? '否' : '是') :
                                newValue || "-";
                        $text.text(showValue).show();
                        $editCtrl.remove();
                        // 刷新表格，保持当前页码
                        $("#bootstrap-table").bootstrapTable("refresh", {
                            pageNumber: $("#bootstrap-table").bootstrapTable("getOptions").pageNumber
                        });
                    } else {
                        $text.show();
                        $editCtrl.remove();
                        $.modal.alertError("保存失败：" + (res.msg || "系统异常"));
                    }
                })
                .fail(function () {
                    $text.show();
                    $editCtrl.remove();
                    $.modal.alertError("网络异常，请重试！");
                });
        }

        // 4. 公用：单元格格式化（统一渲染可编辑文本）
        function cellFormatter(value, row, field) {
            var billId = row.billId !== undefined && row.billId !== null ? row.billId.toString() : "";
            // 格式化显示值（金额加¥，结算状态转文字）
            var showValue;
            if (field === 'actualPay') {
                showValue = '¥' + (parseFloat(value) || 0);
            } else if (field === 'isSettlement') {
                showValue = $.table.selectDictLabel(billIsSettlement, value) || "-";
            } else {
                showValue = value !== null && value !== undefined ? value : "-";
            }
            // 渲染带标识的可编辑文本
            return '<span class="cell-text" style="cursor: pointer;" data-field="' + field + '" data-id="' + billId + '">' + showValue + '</span>';
        }

        // 5. 公用：单元格背景样式（淡蓝色，统一风格）
        function cellBlueBgStyle() {
            return {
                css: {
                    "background-color": "#E6F4FF",
                    "padding": "5px 0",
                    "border-radius": "4px",
                    "text-align": "center"
                }
            };
        }

        var options = {
            url: prefix + "/list",
            updateUrl: prefix + "/edit/{id}",
            exportUrl: prefix + "/export",
            modalName: "琦风公寓-每月账单",
            columns: [{
                checkbox: true
            },
                {
                    field: 'billId',
                    title: '账单id',
                    visible: false
                },
                {
                    field: 'unit',
                    title: '单元号',
                    align: 'center',
                    formatter: function (value, row, index) {
                        return $.table.selectDictLabel(unitTypes, value);
                    }
                },
                {
                    field: 'roomNum',
                    title: '房间',
                    // 排序核心配置
                    sortable: true,  // 启用排序
                    sorter: function (a, b) {  // 自定义排序逻辑
                        const valA = parseInt(a.roomNum) || 0;
                        const valB = parseInt(b.roomNum) || 0;
                        return valA - valB;
                    },
                    sortName: 'roomNum'  // 后端排序字段名（与数据库字段一致）
                },
                {
                    field: 'rent',
                    title: '租金(元)',
                    // 添加格式化函数，在数值前加上人民币符号
                    formatter: function (value, row, index) {
                        // 确保值是数字类型，如果为空则显示0
                        return '¥' + (parseFloat(value) || 0);
                    }
                },
                {
                    field: 'rentPayDate',
                    title: '交租日',
                    // 排序核心配置
                    sortable: true,  // 启用排序
                    sorter: function (a, b) {  // 自定义排序逻辑
                        const valA = parseInt(a.rentPayDate) || 0;
                        const valB = parseInt(b.rentPayDate) || 0;
                        return valA - valB;
                    },
                    sortName: 'rentPayDate'  // 后端排序字段名（与数据库字段一致）
                },
                {
                    field: 'lastMonthWater',
                    title: '上月水'
                },
                {
                    field: 'thisMonthWater',
                    title: '本月水',
                    align: 'center',
                    // 复用公用格式化函数
                    formatter: function (value, row, index) {
                        return cellFormatter(value, row, 'thisMonthWater');
                    },
                    events: {
                        'click .cell-text': function (e, value, row, index) {
                            // 复用公用编辑逻辑（输入框类型）
                            var editData = cellEditHandler(e, row, index, 'input');
                            if (!editData) return;
                            // 失焦保存
                            editData.$editCtrl.on("blur", function () {
                                cellSaveHandler(editData);
                            });
                            // Enter键保存
                            editData.$editCtrl.on("keydown", function (e) {
                                if (e.keyCode === 13) $(this).blur();
                            });
                        }
                    },
                    // 复用公用背景样式
                    cellStyle: cellBlueBgStyle
                },
                {
                    field: 'waterUsage',
                    title: '用水量'
                },
                {
                    field: 'waterRate',
                    title: '水费(元)',
                    // 添加格式化函数，在数值前加上人民币符号
                    formatter: function (value, row, index) {
                        // 确保值是数字类型，如果为空则显示0
                        return '¥' + (parseFloat(value) || 0);
                    }
                },
                {
                    field: 'lastMonthElectricity',
                    title: '上月电'
                },
                {
                    field: 'thisMonthElectricity',
                    title: '本月电',
                    align: 'center',
                    // 复用公用函数
                    formatter: function (value, row, index) {
                        return cellFormatter(value, row, 'thisMonthElectricity');
                    },
                    events: {
                        'click .cell-text': function (e, value, row, index) {
                            var editData = cellEditHandler(e, row, index, 'input');
                            if (!editData) return;
                            editData.$editCtrl.on("blur", function () {
                                cellSaveHandler(editData);
                            });
                            editData.$editCtrl.on("keydown", function (e) {
                                if (e.keyCode === 13) $(this).blur();
                            });
                        }
                    },
                    cellStyle: cellBlueBgStyle
                },
                {
                    field: 'electricityUsage',
                    title: '用电量'
                },
                {
                    field: 'electricityBill',
                    title: '电费(元)',
                    // 添加格式化函数，在数值前加上人民币符号
                    formatter: function (value, row, index) {
                        // 确保值是数字类型，如果为空则显示0
                        return '¥' + (parseFloat(value) || 0);
                    }
                },
                {
                    field: 'sanitationFee',
                    title: '卫生费(元)',
                    // 添加格式化函数，在数值前加上人民币符号
                    formatter: function (value, row, index) {
                        // 确保值是数字类型，如果为空则显示0
                        return '¥' + (parseFloat(value) || 0);
                    }
                },
                {
                    field: 'receivable',
                    title: '应收款(元)',
                    // 添加格式化函数，在数值前加上人民币符号
                    formatter: function (value, row, index) {
                        // 确保值是数字类型，如果为空则显示0
                        return '¥' + (parseFloat(value) || 0);
                    }
                },
                // 新增：实收款可编辑（复用公用函数）
                {
                    field: 'actualPay',
                    title: '实收款(元)',
                    align: 'center',
                    formatter: function (value, row, index) {
                        return cellFormatter(value, row, 'actualPay');
                    },
                    events: {
                        'click .cell-text': function (e, value, row, index) {
                            // 实收款用小数输入框（step=0.01）
                            var editData = cellEditHandler(e, row, index, 'input');
                            if (!editData) return;
                            editData.$editCtrl.on("blur", function () {
                                cellSaveHandler(editData);
                            });
                            editData.$editCtrl.on("keydown", function (e) {
                                if (e.keyCode === 13) $(this).blur();
                            });
                        }
                    },
                    cellStyle: cellBlueBgStyle
                },
                // 新增：是否结算可编辑（下拉选择）
                {
                    field: 'isSettlement',
                    title: '是否结算',
                    align: 'center',
                    formatter: function (value, row, index) {
                        return cellFormatter(value, row, 'isSettlement');
                    },
                    events: {
                        'click .cell-text': function (e, value, row, index) {
                            // 结算状态用下拉框类型
                            var editData = cellEditHandler(e, row, index, 'select');
                            if (!editData) return;
                            // 下拉框改变时直接保存（无需失焦）
                            editData.$editCtrl.on("change", function () {
                                cellSaveHandler(editData);
                            });
                        }
                    },
                    cellStyle: function () {
                        return {
                            css: {
                                "background-color": "#E8F5E9", // 浅绿色，与金额字段区分
                                "padding": "5px 0",
                                "border-radius": "4px",
                                "text-align": "center"
                            }
                        };
                    }
                },
                {
                    field: 'billChart',
                    title: '账单图片',
                    align: 'center',
                    formatter: function (value, row, index) {
                        if (!value) {
                            return "<span class='text-gray'>未生成</span>";
                        }
                        // 直接使用后端返回的URL（含Constants.RESOURCE_PREFIX）
                        return '<img src="' + value + '" style="width: 80px; height: auto; cursor: pointer;" onclick="zoomBillImage(\'' + value + '\')" title="点击放大查看" />';
                    }
                },
                {
                    field: 'remark',
                    title: '备注'
                },
                {
                    title: '操作',
                    align: 'center',
                    formatter: function (value, row, index) {
                        var actions = [];
                        actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.billId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
                        // 新增：生成账单按钮（仅对未结算账单显示，可根据需求调整）
                        actions.push('<a class="btn btn-primary btn-xs" href="javascript:void(0)" onclick="generateBillImage(\'' + row.billId + '\')"><i class="fa fa-image"></i>生成账单</a> ');
                        return actions.join('');
                    }
                }]
        };
        $.table.init(options);
    });

    // 全局变量：存储当前选中的账单ID和生成的图片Base64
    var currentBillId = "";
    var generatedImageBase64 = "";

    // 全局变量存储基础电费（默认值备用）
    var baseElectricityFee = "0.84";

    /**
     * 从后端获取基础电费（适配最新接口返回格式）
     * @param {Function} callback 回调函数（确保基础电费加载完成后执行）
     */
    function getBaseElectricityFee(callback) {
        $.ajax({
            url: prefix + "/getBaseElectricityFee", // 后端接口地址
            type: "get",
            dataType: "json",
            success: function (res) {
                console.log("基础电费接口完整返回：", res);
                // 1. 验证接口返回是否成功（code=0 对应 Type.SUCCESS）
                if (res && res.code === 0) {
                    // 2. 提取 data 字段中的基础电费（可能为字符串，需转为数字）
                    var fee = parseFloat(res.msg);
                    // 3. 验证是否为有效数字，无效则使用默认值
                    if (!isNaN(fee)) {
                        baseElectricityFee = fee.toFixed(2); // 保留两位小数
                        console.log("获取基础电费成功：", baseElectricityFee);
                    } else {
                        console.warn("基础电费格式错误，使用默认值");
                    }
                } else {
                    // 接口返回失败（如 code!=0），使用默认值
                    console.warn("获取基础电费失败，错误信息：", res.msg || "未知错误");
                }
                // 执行回调（无论成功失败，确保后续逻辑能继续）
                if (typeof callback === "function") {
                    callback();
                }
            },
            error: function (xhr) {
                // 网络错误处理
                console.error("获取基础电费接口请求失败：", xhr.statusText);
                if (typeof callback === "function") {
                    callback();
                }
            }
        });
    }

    /**
     * 打开账单生成弹框（加载当前账单数据）
     *
     */
    function generateBillImage(billId) {
        currentBillId = billId;
        // 1. 重置弹框状态（保留确认保存按钮显示，无需隐藏）
        $("#generatedImageContainer").hide();
        $("#generatedImage").attr("src", "");
        generatedImageBase64 = "";
        // 关键：先获取基础电费，再加载账单数据
        getBaseElectricityFee(function () {
            // 2. 加载当前账单数据（调用后端接口获取完整账单信息）
            $.ajax({
                url: prefix + "/get/" + billId, // 后端已新增的接口
                type: "get",
                dataType: "json",
                success: function (res) {
                    console.log("后端返回数据:", res);
                    // 关键修正：根据AjaxResult的Type.SUCCESS，成功状态码为0
                    if (res.code === 0) {
                        var bill = res.data || {}; // 确保数据对象存在
                        // 1. 电费单价：使用从后端获取的基础电费
                        $("#previewElectricityUnitPrice").text(baseElectricityFee);
                        // 2. 公共事业服务费：房间电单价（bill中的字段） - 基础电费
                        // 假设房间电单价字段为 electricityUnitPrice（需与后端确认）
                        var roomElectricityPrice = parseFloat(bill.electricityUnitPrice || 0);
                        var publicServicePrice = (roomElectricityPrice - parseFloat(baseElectricityFee)).toFixed(2);
                        // 避免负数，最小为0
                        publicServicePrice = Math.max(0, publicServicePrice).toFixed(2);
                        $("#previewPublicServiceUnitPrice").text(publicServicePrice);

                        // 3. 渲染预览模板（适配收据格式）
                        // 账单编号补零（示例：固定7位，不足补零）
                        var formattedBillNumber = (bill.billNumber || 0).toString().padStart(7, "0");
                        $("#previewBillNumber").text(formattedBillNumber);
                        // 基础信息
                        $("#previewUserName").text(bill.userName || "--");
                        // 核心修改：数字单元号（1/2）转中文显示（一单元/二单元）
                        var unitText = ""; // 存储转换后的单元文本
                        if (bill.unit === "1" || bill.unit === 1) { // 兼容字符串/数字类型的1
                            unitText = "一单元";
                        } else if (bill.unit === "2" || bill.unit === 2) { // 兼容字符串/数字类型的2
                            unitText = "二单元";
                        } else {
                            unitText = "-"; // 无数据时显示默认值
                        }
                        // 将转换后的文本赋值给DOM
                        $("#previewUnit").text(unitText);
                        $("#previewRoomNum").text(bill.roomNum || "-");

                        // 日期处理（当前日期）
                        var now = new Date();
                        $("#previewDate").text(
                            now.getFullYear() + "年" +
                            (now.getMonth() + 1).toString().padStart(2, "0") + "月" +
                            now.getDate().toString().padStart(2, "0") + "日"
                        );

                        // 水费数据（严格对应收据字段）
                        $("#previewWaterThisMonth").text(bill.thisMonthWater || "0");
                        $("#previewWaterLastMonth").text(bill.lastMonthWater || "0");
                        $("#previewWaterUsage").text(bill.waterUsage || "0");
                        $("#previewWaterUnitPrice").text(bill.waterUnitPrice || "5.00"); // 水单价
                        $("#previewWaterAmount").text(bill.waterRate || "0.00"); // 水费金额

                        // 电费数据
                        $("#previewElectricityThisMonth").text(bill.thisMonthElectricity || "0");
                        $("#previewElectricityLastMonth").text(bill.lastMonthElectricity || "0");
                        $("#previewElectricityUsage").text(bill.electricityUsage || "0");
                        // $("#previewElectricityUnitPrice").text(bill.electricityUnitPrice || "0.84"); // 电单价
                        $("#previewElectricityAmount").text(bill.electricityBill || "0.00"); // 电费金额

                        // 公共事业服务费（如物业费）
                        // $("#previewPublicServiceUnitPrice").text(bill.publicServiceUnitPrice || "0.46");
                        $("#previewPublicServiceUnitPrice").text(publicServicePrice); // 使用计算后的值
                        $("#previewPublicServiceAmount").text(bill.publicServiceFee || "0.00");

                        // 房租
                        $("#previewRent").text(bill.rent || "0.00");
                        $("#previewRentAmount").text(bill.rent || "0.00");

                        // 卫生费
                        $("#previewSanitationFee").text(bill.sanitationFee || "0.00");

                        // 合计金额计算
                        var total = [
                            parseFloat(bill.rent) || 0,
                            parseFloat(bill.waterRate) || 0,
                            parseFloat(bill.electricityBill) || 0,
                            parseFloat(bill.publicServiceFee) || 0,
                            parseFloat(bill.sanitationFee) || 0
                        ].reduce((a, b) => a + b, 0); // 累加所有费用
                        $("#previewTotalAmount").text(total.toFixed(2));

                        // 金额大写转换（完善版）
                        $("#previewTotalAmountCapital").text(numberToChinese(total));

                        // 开票人与收款人（可从系统获取当前登录用户）
                        $("#previewIssuer").text(bill.drawer || "锜风公寓");
                        $("#previewCollector").text(bill.payee || "锜风公寓");

                        // 4. 显示弹框
                        $("#billImageModal").modal("show");

                        // 【关键修改】延长延迟到300ms，确保DOM完全渲染（复杂DOM需更长时间）
                        setTimeout(function () {
                            var previewDom = document.getElementById("billPreview");
                            // 1. 检查DOM是否存在
                            if (!previewDom) {
                                console.error("账单预览DOM不存在！请检查id='billPreview'的元素");
                                $.modal.alertError("图片生成失败，页面元素异常！");
                                return;
                            }
                            // 2. 检查DOM是否有内容（避免空DOM）
                            var previewContent = previewDom.innerText.trim();
                            if (previewContent === "" || previewContent.length < 10) {
                                console.error("账单预览DOM内容为空！当前内容：", previewContent);
                                $.modal.alertError("图片生成失败，预览内容未加载！");
                                return;
                            }
                            // 3. 检查DOM是否可见（避免隐藏状态）
                            var isVisible = window.getComputedStyle(previewDom).display !== "none" &&
                                window.getComputedStyle(previewDom).visibility === "visible" &&
                                previewDom.offsetHeight > 0; // 确保有实际高度
                            if (!isVisible) {
                                console.error("账单预览DOM不可见！当前样式：", window.getComputedStyle(previewDom));
                                $.modal.alertError("图片生成失败，预览区域不可见！");
                                return;
                            }

                            // 4. 此时DOM已确保存在、有内容、可见，执行html2canvas
                            html2canvas(previewDom, {
                                scale: 2,          // 高清生成
                                useCORS: true,     // 允许跨域（如果有外部图片）
                                logging: false,
                                allowTaint: true,  // 解决样式污染导致的生成失败
                                backgroundColor: "#fff" // 明确背景色，避免透明导致的空画布
                            }).then(function (canvas) {
                                generatedImageBase64 = canvas.toDataURL("image/png");
                                // 打印调试日志（确认结果）
                                console.log("生成的Base64前100字符：", generatedImageBase64.substring(0, 100));
                                console.log("Base64完整长度：", generatedImageBase64.length);

                                // 格式检查
                                if (!generatedImageBase64.startsWith("data:image/png;base64,")) {
                                    console.error("Base64格式异常（完整值）：", generatedImageBase64);
                                    $.modal.alertError("图片生成失败，格式异常，请重试！");
                                    $("#generatedImageContainer").hide();
                                    return;
                                }
                                // 格式正确，显示图片
                                $("#generatedImage").attr("src", generatedImageBase64);
                                $("#generatedImageContainer").show();
                            });
                        }, 300); // 延迟300ms，足够复杂DOM渲染完成
                    } else {
                        // 错误处理（使用后端返回的msg）
                        $.modal.alertError("加载失败：" + (res.msg || "未知错误"));
                    }
                },
                error: function (xhr) {
                    // 网络错误处理
                    console.error("请求异常:", xhr);
                    $.modal.alertError("网络异常，请检查连接后重试");
                }
            });
        });

    }

    /**
     * 数字转中文大写金额（工具函数）
     */
    function numberToChinese(num) {
        if (isNaN(num) || num < 0) return "零元整";
        num = Math.round(num * 100) / 100; // 保留两位小数
        const digits = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"];
        const units = ["", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿"];
        const decimals = ["角", "分"];

        let integerPart = Math.floor(num);
        let decimalPart = Math.round((num - integerPart) * 100);
        let result = "";

        // 处理整数部分
        if (integerPart === 0) {
            result += "零";
        } else {
            let str = integerPart.toString();
            for (let i = 0; i < str.length; i++) {
                let digit = parseInt(str[i]);
                let unitIndex = str.length - 1 - i;
                if (digit !== 0) {
                    result += digits[digit] + units[unitIndex];
                } else {
                    // 避免连续多个零
                    if (str[i - 1] !== '0' || result.charAt(result.length - 1) !== '零') {
                        result += digits[digit];
                    }
                    // 补上万/亿单位
                    if (units[unitIndex] === "万" || units[unitIndex] === "亿") {
                        result += units[unitIndex];
                    }
                }
            }
        }
        result += "元";

        // 处理小数部分
        if (decimalPart === 0) {
            result += "整";
        } else {
            let jiao = Math.floor(decimalPart / 10);
            let fen = decimalPart % 10;
            if (jiao > 0) result += digits[jiao] + decimals[0];
            if (fen > 0) result += digits[fen] + decimals[1];
        }
        return result;
    }


    /**
     * 保存图片到后端数据库
     */
    $("#saveBtn").click(function () {
        if (!generatedImageBase64) {
            $.modal.alertWarning("图片正在生成中，请稍候...");
            return;
        }

        // 关键修复：确保Base64字符串包含完整前缀
        let imageBase64 = generatedImageBase64;
        const requiredPrefix = "data:image/png;base64,";
        // 如果前缀缺失则自动补全
        if (!imageBase64.startsWith(requiredPrefix)) {
            imageBase64 = requiredPrefix + imageBase64;
            console.warn("自动补全了缺失的Base64前缀");
        }

        // 显示保存中提示
        $.modal.loading("正在保存账单图片，请稍候...");
        // 发送Base64图片到后端（使用补全后的imageBase64）
        $.ajax({
            url: prefix + "/uploadBillImage",
            type: "post",
            dataType: "json",
            contentType: "application/json",
            data: JSON.stringify({
                billId: currentBillId,
                billImageBase64: imageBase64  // 使用处理后的Base64字符串
            }),
            success: function (res) {
                $.modal.closeLoading(); // 关闭加载提示
                console.log(res)
                if (res.code === 0) {
                    $.modal.alertSuccess("账单图片保存成功！");
                    $("#billImageModal").modal("hide");
                    $.table.refresh();
                } else {
                    $.modal.alertError("保存失败：" + res.msg);
                }
            },
            error: function () {
                $.modal.closeLoading(); // 关闭加载提示
                $.modal.alertError("保存图片异常，请重试！");
            }
        });
    });

    /**
     * 放大查看账单图片
     */
    function zoomBillImage(imageUrl) {
        $("#zoomImage").attr("src", imageUrl);
        $("#imageZoomModal").modal("show");
    }

    /**
     * 生成本月账单
     */
    function generateCurrentMonthBills() {
        // 显示确认对话框
        $.modal.confirm("确定要生成本月的所有账单吗？此操作可能需要几分钟时间。", function () {
            // 显示加载中提示
            $.modal.loading("正在生成本月账单，请稍候...");

            // 调用后端接口生成本月账单
            $.ajax({
                url: prefix + "/generateCurrentMonthBills",
                type: "post",
                dataType: "json",
                success: function (res) {
                    // 关闭加载提示
                    $.modal.closeLoading();
                    console.log(res)
                    if (res.code === 0) {
                        $.modal.alertSuccess("本月账单生成成功，共生成 " + res.data + " 条账单记录！");
                        // 刷新表格显示新生成的账单
                        $.table.refresh();
                    } else {
                        $.modal.alertError("生成失败：" + (res.msg || "未知错误"));
                    }
                },
                error: function () {
                    // 关闭加载提示
                    $.modal.closeLoading();
                    $.modal.alertError("生成账单时发生网络错误，请重试！");
                }
            });
        });
    }


</script>
</body>

</html>